46th Australian Parliament basic statistics¶

Note you will have needed to run the download.sh script to get the data.

In [1]:
import os
import pathlib
import plotly.express as px

# set plotly express to white theme
px.defaults.template = "plotly_white"
from dotenv import load_dotenv
from sqlalchemy import create_engine
import matplotlib.pyplot as plt

%matplotlib inline

load_dotenv("../.env")

USE_POSTGRES = os.environ.get('DATABASE_USERNAME', False)
# USE_POSTGRES = False

root_data_dir = pathlib.Path("..").resolve() / "data"
ext_data_dir = root_data_dir / "external"
geopackage = root_data_dir / "aped.gpkg"
if USE_POSTGRES:
    engine = create_engine(
        f"postgresql+psycopg://{os.environ.get('DATABASE_USERNAME')}:{os.environ.get('DATABASE_PASSWORD')}@localhost:5432/{os.environ.get('DATABASE_NAME')}")
else:
    import sqlite3

    engine = sqlite3.connect(geopackage)
G10_colors = px.colors.qualitative.G10
PARTY_COLOUR_MAP = {"Australian Greens": G10_colors[7], "Australian Labor Party": G10_colors[8],
                    "Coalition": G10_colors[9], "Independent": G10_colors[4]}
In [2]:
import pandas as pd

members = pd.read_sql("SELECT * from member_aph_46", engine)
members
Out[2]:
id member_id member party party_abbrev district is_senator is_representative mp_id start ... RepresentedMinistries RepresentedShadowMinistries ParliamentaryPositions Honours Occupations SecondaryOccupations Qualifications ElectorateService PartyParliamentaryService PartyCommitteeService
0 1 128 Eric Abetz Coalition LNP Tasmania True False N26 1994-02-22 ... [Parliamentary Secretary, Special Minister of ... [Shadow Minister, Shadow Minister, Shadow Mini... [] {} [Barrister and solicitor] [Barrister, Legal, Social and Welfare Professi... [Bachelor of Arts, University of Tasmania, Bac... [] [{'RoSId': 26985, 'RoSType': 'Parliamentary Se... [{'RoSId': 943, 'RoSType': 'Committee Service'...
1 2 54 Anthony Albanese Australian Labor Party ALP Grayndler False True R36 1996-03-02 ... [Cabinet Minister, Cabinet Minister, Cabinet M... [Shadow Parliamentary Secretary, Shadow Parlia... [] {} [Senior Policy Adviser to the Premier, the Hon... [Credit or Loans Officer, Numerical Clerks, Cl... [Bachelor of Economics, University of Sydney] [{'Electorate': 'Grayndler', 'State': 'New Sou... [{'RoSId': 27149, 'RoSType': 'Parliamentary Se... [{'RoSId': 1127, 'RoSType': 'Committee Service...
2 3 187 John Alexander Coalition LNP Bennelong False True M3M 2010-08-21 ... [] [] [] {"Australian Sports Medal, 2000","Awarded a Me... [Federation Cup Captain/Coach, 2005., Sports c... [Tennis Coach, Sportspersons nec, Chief Execut... [] [{'Electorate': 'Bennelong', 'State': 'New Sou... [{'RoSId': 27156, 'RoSType': 'Parliamentary Se... [{'RoSId': 1133, 'RoSType': 'Committee Service...
3 4 52 Katie Allen Coalition LNP Higgins False True 282986 2019-05-18 ... [] [] [] {"Fellow of the Australian Academy of Health a... [Scientific Advisory Board Member at Before Br... [Life Scientists nec, Research and Development... [Doctor of Philosophy, University of Melbourne... [{'Electorate': 'Higgins', 'State': 'Victoria'... [{'RoSId': 54212, 'RoSType': 'Parliamentary Se... [{'RoSId': 54504, 'RoSType': 'Committee Servic...
4 5 235 Anne Aly Australian Labor Party ALP Cowan False True 13050 2016-07-02 ... [Minister, Minister] [] [] {"Australian Security Medal, 2016","Member, WA... [Professorial Fellow, 2015., Associate Profess... [Human Resource Manager, University Lecturer, ... [Doctor of Philosophy, Edith Cowan University,... [{'Electorate': 'Cowan', 'State': 'Western Aus... [{'RoSId': 27146, 'RoSType': 'Parliamentary Se... [{'RoSId': 1122, 'RoSType': 'Committee Service...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
231 232 205 Jason Wood Coalition LNP La Trobe False True E0F 2013-09-07 ... [Assistant Minister] [Shadow Parliamentary Secretary, Shadow Parlia... [] {"Awarded a Centenary Medal, 01.01.2001","Quee... [Senior Sergeant in the Counter Terrorism Coor... [Police Officer, Detective, Protective Service... [Graduate Diploma Innovation Service Managemen... [{'Electorate': 'La Trobe', 'State': 'Victoria... [{'RoSId': 27705, 'RoSType': 'Parliamentary Se... [{'RoSId': 2472, 'RoSType': 'Committee Service...
232 233 265 Ken Wyatt Coalition LNP Hasluck False True M3A 2010-08-21 ... [Assistant Minister, Assistant Minister, Assis... [] [] {"Indigenous Education Warrior Award, World In... [Director for Aboriginal Health at the Departm... [Management Consultant, Policy and Planning Ma... [Bachelor of Education, Churchlands College of... [{'Electorate': 'Hasluck', 'State': 'Western A... [{'RoSId': 27710, 'RoSType': 'Parliamentary Se... [{'RoSId': 2479, 'RoSType': 'Committee Service...
233 234 242 Terry Young Coalition LNP Longman False True 201906 2019-05-18 ... [] [] [Member of the Speaker's Panel] {} [Franchisee, Drummond Golf, Maroochydore from ... [Other Factory Process Workers nfd, Service St... [] [{'Electorate': 'Longman', 'State': 'Queenslan... [{'RoSId': 54008, 'RoSType': 'Parliamentary Se... [{'RoSId': 54534, 'RoSType': 'Committee Servic...
234 235 230 Tony Zappia Australian Labor Party ALP Makin False True HWB 2007-11-24 ... [] [Shadow Parliamentary Secretary, Shadow Parlia... [] {} [Fitness centre manager from 1981 to 2007., Re... [Bank Worker, Fitness Centre Manager, Numerica... [] [{'Electorate': 'Makin', 'State': 'South Austr... [{'RoSId': 27719, 'RoSType': 'Parliamentary Se... [{'RoSId': 2501, 'RoSType': 'Committee Service...
235 236 63 Trent Zimmerman Coalition LNP North Sydney False True 203092 2015-12-05 ... [] [] [Member of the Speaker's Panel] {} [Deputy Chief Executive Officer and Director o... [Information and Organisation Professionals ne... [] [{'Electorate': 'North Sydney', 'State': 'New ... [{'RoSId': 27723, 'RoSType': 'Parliamentary Se... [{'RoSId': 2508, 'RoSType': 'Committee Service...

236 rows × 62 columns

Sanity checking the data Demographic details

In [3]:
party_counts = members.groupby(["party", "Gender"]).size().reset_index(name='count')
party_counts["%"] = (party_counts["count"] / party_counts.groupby("party")["count"].transform("sum")) * 100
party_counts
Out[3]:
party Gender count %
0 Australian Greens Female 7 58.333333
1 Australian Greens Male 5 41.666667
2 Australian Labor Party Female 47 48.453608
3 Australian Labor Party Male 50 51.546392
4 Centre Alliance Female 1 50.000000
5 Centre Alliance Male 1 50.000000
6 Coalition Female 29 25.438596
7 Coalition Male 85 74.561404
8 Independent Female 2 40.000000
9 Independent Male 3 60.000000
10 Jacqui Lambie Network Female 1 100.000000
11 Katter's Australian Party Male 1 100.000000
12 Liberal Democratic Party Female 1 100.000000
13 Pauline Hanson's One Nation Female 1 50.000000
14 Pauline Hanson's One Nation Male 1 50.000000
15 United Australia Party [2018] Male 1 100.000000
In [4]:
# create a cut of members by age
from datetime import date

today = date.today()
members["age"] = pd.to_datetime(members["dob"]).apply(
    lambda x: today.year - x.year - ((today.month, today.day) < (x.month, x.day)))
members["age_group"] = pd.cut(members["age"], bins=[18, 21, 30, 40, 50, 60, 70, 80, 90, 159],
                              labels=["18-20", "21-30", "31-40", "41-50", "51-60", "61-70", "71-80", "81-90", "91+"],
                              ordered=False)
age_counts = members.groupby(["Gender", "chamber", "age_group"]).size().reset_index(name='count')
# create a plot of members by age_counts
import plotly.express as px

px.bar(age_counts, x="age_group", y="count", color="Gender", barmode="group", facet_col="chamber",
       title="Age breakdown of Australian politicians by chamber")
In [5]:
# two female memebers missing 2 male members 4 male senators
chamber_counts = members.groupby(["Gender", "chamber"]).size().reset_index(name='count')
px.bar(age_counts, x="chamber", y="count", color="Gender", barmode="group", title="Gender breakdown by chamber")
In [6]:
# calculate members age using their date of birth grouped by party
from datetime import date

today = date.today()
members["age"] = pd.to_datetime(members["dob"]).apply(
    lambda x: today.year - x.year - ((today.month, today.day) < (x.month, x.day)))
members.groupby(["party"]).agg({"age": ["mean", "std"]})
Out[6]:
age
mean std
party
Australian Greens 50.583333 9.624385
Australian Labor Party 54.144330 9.137822
Centre Alliance 57.500000 10.606602
Coalition 53.168142 8.774865
Independent 56.000000 5.196152
Jacqui Lambie Network 52.000000 NaN
Katter's Australian Party 77.000000 NaN
Liberal Democratic Party 55.000000 NaN
Pauline Hanson's One Nation 68.000000 0.000000
United Australia Party [2018] 59.000000 NaN
In [7]:
import plotly.express as px

fig = px.bar(party_counts, x="party", y="%", color="Gender",
             title="Gender breakdown of Australian politicians by party")
fig.add_shape(  # add a horizontal "target" line for 50%
    type="line", line_color="salmon", line_width=3, opacity=1, line_dash="dot",
    x0=0, x1=1, xref="paper", y0=50, y1=50, yref="y"
)

fig.show()
In [8]:
members_education = pd.read_sql("""
SELECT * from member_secondary_school_education_46
""", engine)
In [9]:
members_education["al_school_sector"].value_counts()
Out[9]:
al_school_sector
Government     119
Independent     79
Catholic        59
Name: count, dtype: int64
In [10]:
school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
    ["party", "school_sector"]).size().reset_index(name='count')
school_sector_counts
Out[10]:
party school_sector count
0 Australian Greens Non-government 4
1 Australian Greens Public 7
2 Australian Labor Party Non-government 41
3 Australian Labor Party Public 53
4 Centre Alliance Non-government 1
5 Centre Alliance Public 1
6 Coalition Non-government 73
7 Coalition Public 41
8 Independent Non-government 4
9 Independent Public 1
10 Jacqui Lambie Network Public 1
11 Katter's Australian Party Public 1
12 Liberal Democratic Party Public 1
13 Pauline Hanson's One Nation Non-government 1
14 Pauline Hanson's One Nation Public 2
15 United Australia Party [2018] Public 1
In [11]:
# create a plot of members school sector type by party

school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
    ["school_sector", "party", ]).size().reset_index(name='count')
fig = px.bar(school_sector_counts, x="party", y="count", color="school_sector", barmode="group",
             title="School sector breakdown of Australian politicians by party")
fig.show()

members

In [12]:
school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
    ["party", "school_sector"]).size().reset_index(name='count')
fig = px.bar(school_sector_counts, x="school_sector", y="count", color="party",
             title="School sector breakdown of Australian politicians by party",
             color_discrete_map=PARTY_COLOUR_MAP,
             template="plotly_white")
fig.show()

Educational school sector split of politicians¶

Public is Government 64.4605631350012 Catholic 19.6750931104224 Independent 15.8643437545764

46th Parliament is Government 47% Catholic 20% Independent 33%

In [13]:
population_school_sector = {
    "Catholic": 19.7,
    "Government": 64.5,
    "Independent": 15.8643437545764}
pop_school_sector = pd.DataFrame.from_dict(population_school_sector, orient="index").reset_index()
pop_school_sector["group"] = "Australian Population"
pop_school_sector.columns = ["school_sector", "%", "group"]
pop_school_sector
Out[13]:
school_sector % group
0 Catholic 19.700000 Australian Population
1 Government 64.500000 Australian Population
2 Independent 15.864344 Australian Population
In [14]:
# create a plot of members as a percentage school sector

school_sector_counts = members_education.drop_duplicates(["member", "al_school_sector"]).groupby(
    ["al_school_sector"]).size().reset_index(name='count')
school_sector_counts.rename(columns={"al_school_sector": "school_sector"}, inplace=True)
school_sector_counts["%"] = (school_sector_counts["count"] / school_sector_counts["count"].sum()) * 100
school_sector_counts["group"] = "Australian Politicians"

fig = px.bar(pd.concat([school_sector_counts, pop_school_sector]), x="school_sector", y="%",
             color="group",
             barmode="group", title="School sector breakdown of Australian politicians")
fig.show()
In [15]:
# create a plot of members as a percentage school sector depending on if is_representative or senate
school_sector_counts = members_education.drop_duplicates(["member", "al_school_sector"]).groupby(
    ["chamber", "al_school_sector"]).size().reset_index(name='count')
school_sector_counts["%"] = (school_sector_counts["count"] / school_sector_counts.groupby("chamber")[
    "count"].transform("sum")) * 100
fig = px.bar(school_sector_counts, x="chamber", y="%", color="al_school_sector",
             title="School sector breakdown of Australian politicians by party", labels={"chamber": "Chamber"})
fig.show()
In [16]:
# lets extract out our acara_financial data and see which school sectors are in our data
import geopandas as gpd

load_dotenv("../.env")

if USE_POSTGRES:
    gdf = gpd.read_postgis(
        'SELECT m.*, "total enrolments" as total_students FROM member_secondary_school_education_46 m LEFT JOIN acara_school_profile_2022 a on m.acara_id = a."acara sml id"::int',
        engine, geom_col='geom')
else:
    gdf_46 = gpd.read_file(geopackage, layer="member_secondary_school_education_46")
    gdf_46 = gdf_46.convert_dtypes()
    asp_46 = gpd.read_file(geopackage, layer="acara_school_profile_2022")[["acara sml id", "total enrolments"]]
    asp_46 = asp_46.convert_dtypes()
    gdf = pd.merge(gdf_46, asp_46, left_on="acara_id", right_on="acara sml id", how="left")
    gdf.rename(columns={"total enrolments": "total_students"}, inplace=True)
gdf = gdf.convert_dtypes()
# fill missing students with min 50 students
gdf["total_students"] = gdf["total_students"].fillna('50').apply(lambda x: '50' if not x else x)
gdf["total_students"] = gdf["total_students"].astype(int)

# Group by party_abbrev and school_sector and avg total government funding
gdf["australian_government_recurrent_funding_per_student"] = gdf[
    "australian_government_recurrent_funding_per_student"].fillna(0).astype(int)
gdf["state__territory_government_recurring_funding_per_student"] = gdf[
    "state__territory_government_recurring_funding_per_student"].fillna(0).astype(int)
gdf["other_private_sources_per_student"] = gdf["other_private_sources_per_student"].fillna(0).astype(int)
gdf["total_gross_income_per_student"] = gdf["total_gross_income_per_student"].fillna(0).astype(int)

# gdf exlpore data
gdf.explore(
    popup=["name", "member", "party_abbrv", "school_sector",
           "total_students"],
    tooltip=["name", "member", "party_abbrv", "school_sector",
             "total_students"])
Out[16]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [17]:
grouped = gdf.groupby(["party_abbrv", "school_sector"]).agg(
    {"other_private_sources_per_student": "mean", "total_gross_income_per_student": "mean"}).reset_index()
px.bar(grouped, x="party_abbrv", y="other_private_sources_per_student", color="school_sector", barmode="group")
In [18]:
px.bar(grouped, x="party_abbrv", y="total_gross_income_per_student", color="school_sector", barmode="group")
In [19]:
# Select most common secondary school from members_secondary_school APH data
most_common_schools = pd.read_sql(
    "SELECT secondaryschool,count(*) as members_attending  FROM members_secondary_school WHERE secondaryschool != '' and secondaryschool is not null GROUP BY secondaryschool ORDER BY count(*) desc limit 10",
    engine)
most_common_schools
Out[19]:
secondaryschool members_attending
0 Scotch College 5
1 St Ignatius College 4
2 St Peter's College 4
3 Wesley College 4
4 Marist College 3
5 Geelong Grammar School 3
6 Norwood High School 2
7 Aquinas College 2
8 Christian Brothers' College 2
9 Scotch College Melbourne 2

Members attending same school¶

In [20]:
# select those who attended the same school get value counts of name and show members who attended the same school
school_counts = members_education["name"].value_counts()
pd.merge(members_education, school_counts[school_counts > 1].reset_index(), left_on="name", right_on="name")[
    ["name", "member", "party", "school_sector", "count"]].sort_values(["name", "member"])
Out[20]:
name member party school_sector count
34 Aquinas College Brendan O'Connor Australian Labor Party Non-government 2
35 Aquinas College Michael Sukkar Coalition Non-government 2
32 Blackburn High School Anne Webster Coalition Public 2
33 Blackburn High School Stephen Irons Coalition Public 2
30 Downlands College Gerard Rennick Coalition Non-government 2
31 Downlands College John Mcveigh Coalition Non-government 2
8 Gawler and District College Angie Bell Coalition Public 2
7 Gawler and District College Simon Birmingham Coalition Public 2
5 Hobart College Eric Abetz Coalition Public 2
6 Hobart College Nick McKim Australian Greens Public 2
4 Hobart Matriculation College Catryna Bilyk Australian Labor Party Non-government 3
3 Hobart Matriculation College Eric Abetz Coalition Non-government 3
2 Hobart Matriculation College Nick McKim Australian Greens Non-government 3
28 Ipswich Grammar School Garth Hamilton Coalition Non-government 2
29 Ipswich Grammar School Paul Scarr Coalition Non-government 2
1 John XXIII College Celia Hammond Coalition Non-government 2
0 John XXIII College Hollie Hughes Coalition Non-government 2
50 Kingston College Bert van Manen Coalition Public 2
51 Kingston College Kristina Keneally Australian Labor Party Public 2
26 Kurri Kurri High School Malcolm Roberts Pauline Hanson's One Nation Public 2
27 Kurri Kurri High School Meryl Swanson Australian Labor Party Public 2
48 Lurnea High School Anne Stanley Australian Labor Party Public 2
49 Lurnea High School Stirling Griff Centre Alliance Public 2
24 Marcellin College Gregory Mirabella Coalition Non-government 2
25 Marcellin College Luke Gosling Australian Labor Party Non-government 2
39 Marist College Canberra Daniel Mulino Australian Labor Party Non-government 2
38 Marist College Canberra David Smith Australian Labor Party Non-government 2
46 Mount Carmel College, Charters Towers Andrew Laming Coalition Public 2
47 Mount Carmel College, Charters Towers Bob Katter Katter's Australian Party Public 2
36 Mount Scopus Memorial College Josh Burns Australian Labor Party Non-government 2
37 Mount Scopus Memorial College Joshua Frydenberg Coalition Non-government 2
44 Notre Dame College, Sheparton Andrew Bragg Coalition Non-government 2
45 Notre Dame College, Sheparton Kim Carr Australian Labor Party Non-government 2
22 Peninsula Grammar Gregory Hunt Coalition Non-government 2
23 Peninsula Grammar Tim Wilson Coalition Non-government 2
20 Prince Alfred College Cory Bernardi Independent Non-government 2
21 Prince Alfred College David Fawcett Coalition Non-government 2
42 Saint Ignatius' College, Riverview Barnaby Joyce Coalition Non-government 2
43 Saint Ignatius' College, Riverview David Gillespie Coalition Non-government 2
19 Scotch College, Melbourne Andrew Giles Australian Labor Party Non-government 2
18 Scotch College, Melbourne Mark Dreyfus Australian Labor Party Non-government 2
16 St Bede's College Andrew Wallace Coalition Non-government 2
17 St Bede's College David Van Coalition Non-government 2
13 St Peter's College Andrew McLachlan Coalition Non-government 3
14 St Peter's College James Stevens Coalition Non-government 3
15 St Peter's College Scott Ryan Coalition Non-government 3
52 Tintern Grammar Bridget McKenzie Coalition Non-government 2
53 Tintern Grammar John Mcveigh Coalition Non-government 2
11 Unley High School Amanda Rishworth Australian Labor Party Public 2
12 Unley High School Mark Butler Australian Labor Party Public 2
40 Wesley College, Victoria Julian Hill Australian Labor Party Non-government 2
41 Wesley College, Victoria Russell Broadbent Coalition Non-government 2
9 Xavier College Bill Shorten Australian Labor Party Non-government 2
10 Xavier College Dan Tehan Coalition Non-government 2
In [21]:
# select members who don't have a high school in education data
pd.read_sql(
    "SELECT * FROM members WHERE id not in (SELECT member_id FROM member_education JOIN education e on member_education.education_id = e.id WHERE e.is_high_school = TRUE ) AND (high_school is null or high_school != 'International' ) ",
    engine)
Out[21]:
id orig_id orig_table member district is_senator is_representative graduated start wiki_link dob mp_id party_id chamber high_school preferred_name aph_name
0 86 3 47 Alex Antic South Australia True False True 2019-07-01 http://www.wikidata.org/entity/Q63520981 1974-12-22 269375 42 senate Public Alex Antic Alexander Antic
1 122 12 46 Vince Connelly Stirling False True True 2019-05-18 http://www.wikidata.org/entity/Q64585316 1978-09-16 282984 42 house Non-government Vince Connelly Vincent Connelly
2 90 106 47 Karen Grogan South Australia True False True 2021-09-21 http://www.wikidata.org/entity/Q108617920 1960-01-01 296331 11 senate None None Karen Grogan
3 243 21 46 Nicolle Flint Boothby False True True 2016-07-02 http://www.wikidata.org/entity/Q25756083 1978-07-15 245550 42 house Non-government None Nicolle Flint
4 75 151 47 Michelle Ananda-Rajah Higgins False True True 2022-05-21 http://www.wikidata.org/entity/Q90398588 1972-12-10 290544 11 house None None Michelle Ananda-Rajah
5 142 188 47 Sam Birrell Nicholls False True True 2022-05-21 http://www.wikidata.org/entity/Q112131083 1975-01-01 288713 42 house None None Sam Birrell
6 99 155 47 Milton Dick Oxley False True True 2016-07-02 http://www.wikidata.org/entity/Q20983429 1972-07-21 53517 11 house Non-government Milton Dick Dugald Dick
7 93 173 47 Peter Khalil Wills False True True 2016-07-02 http://www.wikidata.org/entity/Q25756187 1973-03-23 101351 11 house Non-government None Peter Khalil
8 251 182 47 Rob Mitchell McEwen False True True 2010-08-21 http://www.wikidata.org/entity/Q7340383 1967-09-09 M3E 11 house Public Rob Mitchell Robert Mitchell
9 152 123 47 Llew O'Brien Wide Bay False True False 2016-07-02 http://www.wikidata.org/entity/Q25756234 1972-06-26 265991 42 house None Llew O'Brien Llewellyn O'Brien
10 57 75 47 Graham Perrett Moreton False True True 2007-11-24 http://www.wikidata.org/entity/Q5593142 1966-01-05 HVP 11 house Public None Graham Perrett
11 23 200 47 Stephen Bates Brisbane False True True 2022-05-21 http://www.wikidata.org/entity/Q112150148 1992-11-23 300246 12 house None None Stephen Bates
12 175 219 47 Tracey Roberts Pearce False True True 2022-05-21 http://www.wikidata.org/entity/Q109850050 1960-01-01 157125 11 house None None Tracey Roberts
13 103 48 46 Julian Simmonds Ryan False True True 2019-05-18 http://www.wikidata.org/entity/Q64226194 1985-08-29 282983 42 house Non-government None Julian Simmonds
14 29 49 46 Arthur Sinodinos New South Wales True False True 2011-10-13 http://www.wikidata.org/entity/Q4800293 1957-02-25 BV7 42 senate Public None Arthur Sinodinos
15 160 132 47 Marielle Smith South Australia True False True 2019-07-01 http://www.wikidata.org/entity/Q63531157 1986-12-30 281603 11 senate Both None Marielle Smith
16 207 98 47 Jordon Steele-John Western Australia True False True 2017-11-10 http://www.wikidata.org/entity/Q33139188 1994-10-14 250156 12 senate Home-Schooled None Jordon Steele-John
17 13 86 47 Jana Stewart Victoria True False True 2022-04-06 http://www.wikidata.org/entity/Q111513180 1987-01-01 299352 11 senate None None Jana Stewart
18 222 206 47 Susan Templeman Macquarie False True True 2016-07-02 http://www.wikidata.org/entity/Q25753992 1963-07-30 181810 11 house Public None Susan Templeman
19 67 94 47 Jess Walsh Victoria True False True 2019-07-01 http://www.wikidata.org/entity/Q64711059 1971-05-16 252157 11 senate Non-government None Jess Walsh
20 82 174 47 Peter Whish-Wilson Tasmania True False True 2012-06-20 http://www.wikidata.org/entity/Q7177677 1968-02-24 195565 12 senate Both None Peter Whish-Wilson
In [22]:
from pywaffle import Waffle
import matplotlib.pyplot as plt

# slightly different to SMH as they set those who did not graduate or who attended overseas to other
members_46 = pd.read_sql("SELECT * FROM member_aph_46", engine)
members_46_high_school = members_46.groupby("high_school").size().reset_index(name='count')
members_46_high_school["%"] = (members_46_high_school["count"] / members_46_high_school["count"].sum()) * 100
fig = plt.figure(
  FigureClass=Waffle,
  rows=10,
  columns=int(members_46_high_school["count"].sum() / 10),
  values=members_46_high_school["%"],
  figsize=(12, 5),
  labels=[f"{row[1]['high_school']} ({row[1]['count']})" for row in members_46_high_school.iterrows()],
  colors=G10_colors[:members_46_high_school["high_school"].shape[0]],
  legend={'loc': 'upper left', 'bbox_to_anchor': (1.1, 1)}
)
In [ ]: